home *** CD-ROM | disk | FTP | other *** search
/ United Public Domain Gold 2 / United Public Domain Gold 2.iso / utilities / pu017.dms / pu017.adf / Gadgets / Example12.c < prev    next >
C/C++ Source or Header  |  1990-01-30  |  21KB  |  571 lines

  1. /* Example12                                                             */
  2. /* This program will open a SuperBitmap window which is connected to the */
  3. /* Workbench Screen. The window will use all System Gadgets, and will    */
  4. /* close first when the user has selected the System gadget Close        */
  5. /* window. Inside the window we have put two Proportional gadgets, one   */
  6. /* on the right side, and one at the bottom. With help of these two      */
  7. /* gadgets, the user can move around the BitMap.                         */
  8. /*                                                                       */
  9. /* This example is for experienced programmers only, and uses some       */
  10. /* functions etc which we have not discussed yet. I have, however,       */
  11. /* included it here since it is a good example on how you can combine    */
  12. /* Proportional gadgets with SuperBitmap windows.                        */
  13.  
  14.  
  15.  
  16. #include <intuition/intuition.h>
  17.  
  18.  
  19.  
  20. #define WIDTH      320
  21. #define MAX_WIDTH  640
  22. #define HEIGHT     128
  23. #define MAX_HEIGHT 256
  24. #define DEPTH        2 /* 4 colours. */
  25.  
  26.  
  27.  
  28. /* Tell the C compiler that the function draw_some_boxes will return: */
  29. void draw_some_boxes(); /* Return nothing (void). */
  30.  
  31.  
  32.  
  33. /* Declare three pointers to the three libraries we are going to open: */
  34. struct IntuitionBase *IntuitionBase;
  35. struct GfxBase *GfxBase;
  36. struct LayersBase *LayersBase;
  37.  
  38.  
  39.  
  40. /***********************************************/
  41. /* THE RIGHT PROPORTIONAL GADGET's STRUCTURES: */
  42. /***********************************************/
  43.  
  44. /* We need to declare an Image structure for the knob, but since */
  45. /* Intuition will take care of the size etc of the knob, we do not need */
  46. /* to initialize the Image structure: */
  47. struct Image my_right_image;
  48.  
  49. struct PropInfo my_right_prop_info=
  50. {
  51.   FREEVERT|       /* Flags, the knob should be moved vertically, and */
  52.   AUTOKNOB,       /* Intuition should take care of the knob image. */
  53.   0,              /* HorizPot, 0 since we will not move the knob hor. */
  54.   0,              /* VertPot, start position of the knob. */
  55.   0,              /* HorizBody. 0 since we will not move the knob hor. */
  56.   MAXBODY * HEIGHT / MAX_HEIGHT, /* VertBody. */
  57.  
  58.   /* These variables are initialized and maintained by Intuition: */
  59.  
  60.   0,              /* CWidth */
  61.   0,              /* CHeight */
  62.   0, 0,           /* HPotRes, VPotRes */
  63.   0,              /* LeftBorder */
  64.   0               /* TopBorder */
  65. };
  66.  
  67. struct Gadget my_right_gadget=
  68. {
  69.   NULL,            /* NextGadget, no more gadgets in the list. */
  70.   -15,             /* LeftEdge, 15 pixels out from the right side. */
  71.     9,             /* TopEdge, 9 lines down. */
  72.    16,             /* Width, 16 pixels wide. */
  73.   -17,             /* Height, 17 lines less than the heigh of the wind. */
  74.   GADGHCOMP|       /* Flags, complement the colours when act. */
  75.   GRELRIGHT|       /* LeftEdge relative to the right border. */
  76.   GRELHEIGHT,      /* Height relative to the height of the window. */
  77.   GADGIMMEDIATE|   /* Activation, our program will recieve a message */
  78.   RELVERIFY|       /* when the user has selected this gadget, and when */
  79.                    /* the user has released it. We will also recieve a */ 
  80.   FOLLOWMOUSE,     /* message when the mouse moves while this gadget is */
  81.                    /* activated. */
  82.   PROPGADGET|      /* GadgetType, a Proportional gadget. */
  83.   GZZGADGET,       /* Put the gadget in the Outer window. */
  84.   (APTR) &my_right_image, /* GadgetRender, the knob's Image structure. */
  85.   NULL,            /* SelectRender, NULL since we do not supply the */
  86.                    /* gadget with an alternative image. */
  87.   NULL,            /* GadgetText, no text. */
  88.   NULL,            /* MutualExclude, no mutual exclude. */
  89.   (APTR) &my_right_prop_info, /* SpecialInfo, our PropInfo structure. */
  90.   0,               /* GadgetID, no id. */
  91.   NULL             /* UserData, no user data connected to the gadget. */
  92. };
  93.  
  94.  
  95.  
  96. /************************************************/
  97. /* THE BOTTOM PROPORTIONAL GADGET's STRUCTURES: */
  98. /************************************************/
  99.  
  100. /* We need to declare an Image structure for the knob, but since */
  101. /* Intuition will take care of the size etc of the knob, we do not need */
  102. /* to initialize the Image structure: */
  103. struct Image my_bottom_image;
  104.  
  105. struct PropInfo my_bottom_prop_info=
  106. {
  107.   FREEHORIZ|      /* Flags, the knob should be moved horizontally, and */
  108.   AUTOKNOB,       /* Intuition should take care of the knob image. */
  109.   0,              /* HorizPot, start position of the knob. */
  110.   0,              /* VertPot, 0 since we will not move the knob ver. */
  111.   MAXBODY * WIDTH / MAX_WIDTH, /* HorizBody. */
  112.   0,              /* VertBody, 0 since we will not move the knob ver. */
  113.  
  114.   /* These variables are initialized and maintained by Intuition: */
  115.  
  116.   0,              /* CWidth */
  117.   0,              /* CHeight */
  118.   0, 0,           /* HPotRes, VPotRes */
  119.   0,              /* LeftBorder */
  120.   0               /* TopBorder */
  121. };
  122.  
  123. struct Gadget my_bottom_gadget=
  124. {
  125.   &my_right_gadget,/* NextGadget, no more gadgets in the list. */
  126.     1,             /* LeftEdge, 1 pixel out from the left side. */
  127.    -8,             /* TopEdge, 8 lines above the bottom border. */
  128.   -15,             /* Width, 15 pixels less wide than the window. */
  129.     9,             /* Height, 9 lines heigh. */
  130.   GADGHCOMP|       /* Flags, complement the colours when act. */
  131.   GRELBOTTOM|      /* TopEdge relative to the bottom border. */
  132.   GRELWIDTH,       /* Width relative to the width of the window. */
  133.   GADGIMMEDIATE|   /* Activation, our program will recieve a message */
  134.   RELVERIFY|       /* when the user has selected this gadget, and when */
  135.                    /* the user has released it. We will also recieve a */ 
  136.   FOLLOWMOUSE|     /* message when the mouse moves while this gadget is */
  137.                    /* activated. */
  138.   BOTTOMBORDER,    /* Make the bottom border of the window big enough */
  139.                    /* for this gadge. */
  140.   PROPGADGET|      /* GadgetType, a Proportional gadget. */
  141.   GZZGADGET,       /* Put the gadget in the Outer window. */
  142.   (APTR) &my_bottom_image,/* GadgetRender, the knob's Image structure. */
  143.   NULL,            /* SelectRender, NULL since we do not supply the */
  144.                    /* gadget with an alternative image. */
  145.   NULL,            /* GadgetText, no text. */
  146.   NULL,            /* MutualExclude, no mutual exclude. */
  147.   (APTR) &my_bottom_prop_info, /* SpecialInfo, our PropInfo structure. */
  148.   0,               /* GadgetID, no id. */
  149.   NULL             /* UserData, no user data connected to the gadget. */
  150. };
  151.  
  152.  
  153.  
  154. /******************************/
  155. /* OPEN A SUPERBITMAP WINDOW: */
  156. /******************************/
  157.  
  158. /*************************************************************/
  159. /* 1. Declare and initialize a NewWindow structure with your */
  160. /*    requirements:                                          */
  161. /*************************************************************/
  162.  
  163. /* Declare a pointer to a Window structure: */ 
  164. struct Window *my_window;
  165.  
  166. /* Declare and initialize your NewWindow structure: */
  167. struct NewWindow my_new_window=
  168. {
  169.   10,            /* LeftEdge    x position of the window. */
  170.   30,            /* TopEdge     y positio of the window. */
  171.   WIDTH,         /* Width       200 pixels wide. */
  172.   HEIGHT,        /* Height      dsfsafsadfdsafsad50 lines high. */
  173.   0,             /* DetailPen   Text should be drawn with colour reg. 0 */
  174.   1,             /* BlockPen    Blocks should be drawn with colour reg. 1 */
  175.   CLOSEWINDOW|   /* IDCMPFlags  The window will give us a message if the */
  176.                  /*             user has selected the Close window gad, */
  177.   GADGETDOWN|    /*             or a gadget has been pressed on, or */
  178.   GADGETUP|      /*             a gadge has been released, or */
  179.   NEWSIZE|       /*             the user has changed the size or */
  180.   MOUSEMOVE,     /*             the mouse moved while a gadget was act. */
  181.   SUPER_BITMAP|  /* Flags       SuperBitMap. (No refreshing necessary) */
  182.   GIMMEZEROZERO| /*             It is also a Gimmezerozero window. */
  183.   WINDOWCLOSE|   /*             Close Gadget. */
  184.   WINDOWDRAG|    /*             Drag gadget. */
  185.   WINDOWDEPTH|   /*             Depth arrange Gadgets. */
  186.   WINDOWSIZING|  /*             Sizing Gadget. */
  187.   ACTIVATE,      /*             The window should be Active when opened. */
  188.   &my_bottom_gadget, /* FirstGadget  Pointer to the first gadget. */
  189.   NULL,          /* CheckMark   Use Intuition's default CheckMark (v). */
  190.   "SuperBitMap", /* Title       Title of the window. */
  191.   NULL,          /* Screen      Connected to the Workbench Screen. */
  192.   NULL,          /* BitMap      We will change this later. */
  193.   50,            /* MinWidth    We will not allow the window to become */
  194.   50,            /* MinHeight   smaller than 50 x 50, and not bigger */
  195.   MAX_WIDTH,     /* MaxWidth    than MAX_WIDTH x MAX_HEIGHT. */
  196.   MAX_HEIGHT,    /* MaxHeight */
  197.   WBENCHSCREEN   /* Type        Connected to the Workbench Screen. */
  198. };
  199.  
  200.  
  201.  
  202. /**********************************/
  203. /* 2. Declare a BitMap structure: */
  204. /**********************************/
  205.  
  206. struct BitMap my_bitmap;
  207.  
  208.  
  209.  
  210. main()
  211. {
  212.   /* Boolean variable used for the while loop: */
  213.   BOOL close_me;
  214.   
  215.   BOOL fix_window;
  216.  
  217.   int x, y;
  218.   int new_x, new_y; 
  219.   int delta_x, delta_y;
  220.  
  221.   /* Declare two pointers which the ScrollLayer() function needs: */
  222.   struct Layer *my_layer;
  223.   struct Layer_Info *my_layer_info;
  224.  
  225.   /* Declare a variable in which we will store the IDCMP flag: */
  226.   ULONG class;
  227.  
  228.   /* Declare a pointer to an IntuiMessage structure: */
  229.   struct IntuiMessage *my_message;
  230.  
  231.   /* Variable used for the loops: */
  232.   int loop;
  233.  
  234.  
  235.  
  236.   /* Before we can use Intuition we need to open the Intuition Library: */
  237.   IntuitionBase = (struct IntuitionBase *)
  238.     OpenLibrary( "intuition.library", 0 );
  239.   
  240.   if( IntuitionBase == NULL )
  241.     exit(); /* Could NOT open the Intuition Library! */
  242.  
  243.  
  244.  
  245.   /* Before we can use the function AllocRaster() etc we need to open */
  246.   /* the graphics Library. (See chapter "Amiga C" for more information) */
  247.   GfxBase = (struct GfxBase *)
  248.     OpenLibrary( "graphics.library", 0);
  249.  
  250.   if( GfxBase == NULL )
  251.   {
  252.     /* Could NOT open the Graphics Library! */
  253.  
  254.     /* Close the Intuition Library since we have opened it: */
  255.     CloseLibrary( IntuitionBase );
  256.  
  257.     exit();
  258.   }
  259.  
  260.  
  261.   /* Before we can use the function ScrollLayer() etc we need to open */
  262.   /* the layers Library. (See chapter "Amiga C" for more information) */
  263.   LayersBase = (struct LayersBase *)
  264.     OpenLibrary( "layers.library", 0);
  265.  
  266.   if( LayersBase == NULL )
  267.   {
  268.     /* Could NOT open the Layers Library! */
  269.  
  270.     /* Close the Graphics Library since we have opened it: */
  271.     CloseLibrary( GfxBase );
  272.  
  273.     /* Close the Intuition Library since we have opened it: */
  274.     CloseLibrary( IntuitionBase );
  275.  
  276.     exit();
  277.   }
  278.  
  279.  
  280.  
  281.   /**********************************************************/
  282.   /* 3. Initialize your own BitMap by calling the function: */
  283.   /**********************************************************/
  284.  
  285.   InitBitMap( &my_bitmap, DEPTH, MAX_WIDTH, MAX_HEIGHT );
  286.  
  287.   /* &my_bitmap: A pointer to the my_bitmap structure. */
  288.   /* DEPTH:      Number of bitplanes to use. */
  289.   /* MAX_WIDTH:  The width of the BitMap. */
  290.   /* MAX_HEIGHT: The height of the BitMap. */
  291.  
  292.  
  293.  
  294.   /**********************************************/
  295.   /* 4. Allocate display memory for the BitMap: */
  296.   /**********************************************/
  297.  
  298.   for( loop=0; loop < DEPTH; loop++)
  299.     if((my_bitmap.Planes[loop] = (PLANEPTR)
  300.       AllocRaster( MAX_WIDTH, MAX_HEIGHT )) == NULL )
  301.     {
  302.       /* PANIC! Not enough memory */
  303.  
  304.       /* Deallocate the display memory, Bitplan by Bitplan. */ 
  305.       for( loop=0; loop < DEPTH; loop++)
  306.         if( my_bitmap.Planes[loop] ) /* Deallocate this Bitplan? */
  307.           FreeRaster( my_bitmap.Planes[loop], MAX_WIDTH, MAX_HEIGHT );
  308.  
  309.       /* Close the Layers Library since we have opened it: */
  310.       CloseLibrary( LayersBase );
  311.  
  312.       /* Close the Graphics Library since we have opened it: */
  313.       CloseLibrary( GfxBase );
  314.  
  315.       /* Close the Intuition Library since we have opened it: */
  316.       CloseLibrary( IntuitionBase );
  317.  
  318.       exit();
  319.     }
  320.  
  321.  
  322.  
  323.   /***************************/
  324.   /* 5. Clear all Bitplanes: */
  325.   /***************************/
  326.   
  327.   for( loop=0; loop < DEPTH; loop++)
  328.     BltClear( my_bitmap.Planes[loop], RASSIZE( MAX_WIDTH, MAX_HEIGHT ), 0);
  329.  
  330.   /* The memory we allocated for the Bitplanes, is normaly "dirty", and */
  331.   /* therefore needs cleaning. We can here use the Blitter to clear the */
  332.   /* memory since it is the fastest way to do it, and the easiest. */
  333.   /* RASSIZE is a macro which calculates memory size for a Bitplane of */
  334.   /* the size WIDTH x HEIGHT. We will later go into more details about */
  335.   /* these functions etc, so do not worry about them... yet. */
  336.  
  337.  
  338.  
  339.   /*******************************************************************/
  340.   /* 6. Make sure the NewWindow's BitMap pointer is pointing to your */
  341.   /*    BitMap structure:                                            */
  342.   /*******************************************************************/
  343.  
  344.   my_new_window.BitMap=&my_bitmap;
  345.  
  346.  
  347.  
  348.   /***************************************/
  349.   /* 7. At last you can open the window: */
  350.   /***************************************/
  351.  
  352.   my_window = (struct Window *) OpenWindow( &my_new_window );
  353.  
  354.   /* Have we opened the window succesfully? */
  355.   if(my_window == NULL)
  356.   {
  357.     /* Could NOT open the Window! */
  358.  
  359.     /* Deallocate the display memory, Bitplan by Bitplan. */ 
  360.     for( loop=0; loop < DEPTH; loop++)
  361.       if( my_bitmap.Planes[loop] ) /* Deallocate this Bitplan? */
  362.         FreeRaster( my_bitmap.Planes[loop], MAX_WIDTH, MAX_HEIGHT );
  363.  
  364.     /* Close the Layers Library since we have opened it: */
  365.     CloseLibrary( LayersBase );
  366.  
  367.     /* Close the Graphics Library since we have opened it: */
  368.     CloseLibrary( GfxBase );
  369.  
  370.     /* Close the Intuition Library since we have opened it: */
  371.     CloseLibrary( IntuitionBase );
  372.  
  373.     exit();
  374.   }
  375.  
  376.  
  377.  
  378.   /* We have opened the window, and everything seems to be OK. */
  379.  
  380.  
  381.   
  382.   /* Initialize the two pointers which will be used by the ScrollLayer */
  383.   /* function: */
  384.   my_layer_info=&(my_window->WScreen->LayerInfo);
  385.   my_layer=my_window->RPort->Layer;
  386.  
  387.  
  388.  
  389.   /* We will now draw some boxes in different colours: */
  390.   draw_some_boxes();
  391.  
  392.  
  393.  
  394.   /* We can for the moment see the top left corner of the BitMap: */
  395.   x=0;
  396.   y=0;
  397.  
  398.   /* The window does not need to be redrawn: */
  399.   fix_window=FALSE;
  400.   
  401.   /* The user wants to run the program for the momnt. */
  402.   close_me = FALSE;
  403.  
  404.   /* Stay in the while loop until the user has selected the Close window */
  405.   /* gadget: */
  406.   while( close_me == FALSE )
  407.   {
  408.     /* Wait until we have recieved a message: */
  409.     Wait( 1 << my_window->UserPort->mp_SigBit );
  410.  
  411.     /* We have now recieved one or more messages. */
  412.  
  413.     /* Since we may recieve several messages we stay in the while loop */
  414.     /* and collect, save, reply and execute the messages until there is */
  415.     /* a pause: */
  416.     while(my_message=(struct IntuiMessage *)GetMsg( my_window->UserPort))
  417.     {
  418.       /* GetMsg will return a pointer to a message if there was one, */
  419.       /* else it returns NULL. We will therefore stay in this while loop */
  420.       /* as long as there are some messages waiting in the port. */
  421.       
  422.       /* After we have collected the message we can read it, and save */
  423.       /* any important values which we maybe want to check later: */
  424.       class = my_message->Class;      /* Save the IDCMP flag. */
  425.  
  426.       /* After we have read it we reply as fast as possible: */
  427.       /* REMEMBER! Do never try to read a message after you have replied! */
  428.       /* Some other process has maybe changed it. */
  429.       ReplyMsg( my_message );
  430.  
  431.       /* Check which IDCMP flag was sent: */
  432.       switch( class )
  433.       {
  434.         case CLOSEWINDOW:  /* The user selected the Close window gadget! */
  435.                close_me=TRUE;
  436.                break;
  437.  
  438.         case MOUSEMOVE:    /* The user moved the mouse while one of the */
  439.                            /* Proportional gadgets was activated: */ 
  440.                fix_window=TRUE; /* Redraw the display. */
  441.                break;             
  442.  
  443.         case NEWSIZE:      /* The user has resized the window: */
  444.                /* Change size of the knobs: */
  445.                ModifyProp
  446.                (
  447.                  &my_right_gadget,           /* Pointer to the gadget. */
  448.                  my_window,                  /* Pointer to the window. */
  449.                  NULL,                       /* Not a requester gadget. */
  450.                  my_right_prop_info.Flags,   /* Flags, no change. */
  451.                  0,                          /* HorizPot */
  452.                  my_right_prop_info.VertPot, /* VertPot, no change. */
  453.                  0,                          /* HorizBody */
  454.                                              /* VertBody: */
  455.                  (ULONG) MAXBODY*my_window->Height/MAX_HEIGHT
  456.                );
  457.                ModifyProp
  458.                (
  459.                  &my_bottom_gadget,            /* Pointer to the gadget. */
  460.                  my_window,                    /* Pointer to the window. */
  461.                  NULL,                         /* Not a req. gadget. */
  462.                  my_bottom_prop_info.Flags,    /* Flags, no change. */
  463.                  my_bottom_prop_info.HorizPot, /* HorizPot, no change. */
  464.                  0,                            /* VertPot */
  465.                                                /* HorizBody: */
  466.                  (ULONG) MAXBODY*my_window->Width/MAX_WIDTH,
  467.                  0                             /* VertBody: */
  468.                );
  469.                fix_window=TRUE; /* Redraw the display. */
  470.                break;
  471.         
  472.         case GADGETDOWN:   /* The user has selected one of the gadgets: */
  473.                fix_window=TRUE; /* Redraw the display. */
  474.                break;
  475.              
  476.         case GADGETUP:     /* The user has released one of the gadgets: */
  477.                fix_window=TRUE; /* Redraw the display. */
  478.                break;
  479.       }    
  480.     }
  481.  
  482.  
  483.  
  484.     /* Should we update the window's display? */
  485.     if(fix_window)
  486.     {
  487.       fix_window=FALSE;
  488.             
  489.       /* Calculate what part of the BitMap we should display: */
  490.       new_x= (MAX_WIDTH - my_bottom_prop_info.HorizBody / (float) MAXBODY
  491.              * MAX_WIDTH) * my_bottom_prop_info.HorizPot / (float) MAXPOT;
  492.  
  493.       new_y= (MAX_HEIGHT - my_right_prop_info.VertBody / (float) MAXBODY
  494.              * MAX_HEIGHT) * my_right_prop_info.VertPot / (float) MAXPOT;
  495.  
  496.       delta_x=new_x-x;
  497.       delta_y=new_y-y;
  498.  
  499.       x=new_x;
  500.       y=new_y;
  501.  
  502.       ScrollLayer( my_layer_info, my_layer, delta_x, delta_y );
  503.     }
  504.   }
  505.  
  506.  
  507.  
  508.   /********************************************************************/
  509.   /* 8. Do not forget to close the window, AND deallocate the display */
  510.   /*    memory:                                                       */
  511.   /********************************************************************/
  512.  
  513.   /* We should always close the windows we have opened before we leave: */
  514.   CloseWindow( my_window );
  515.  
  516.   /* Deallocate the display memory, Bitplan by Bitplan. */ 
  517.   for( loop=0; loop < DEPTH; loop++)
  518.     if( my_bitmap.Planes[loop] ) /* Deallocate this Bitplan? */
  519.       FreeRaster( my_bitmap.Planes[loop], MAX_WIDTH, MAX_HEIGHT );
  520.  
  521.  
  522.  
  523.   /* Close the Layers Library since we have opened it: */
  524.   CloseLibrary( LayersBase );
  525.  
  526.   /* Close the Graphics Library since we have opened it: */
  527.   CloseLibrary( GfxBase );
  528.  
  529.   /* Close the Intuition Library since we have opened it: */
  530.   CloseLibrary( IntuitionBase );
  531.   
  532.   /* THE END */
  533. }
  534.  
  535.  
  536.  
  537. /* This function draws some coloured boxes: */
  538. /* Returns nothing. */
  539. void draw_some_boxes()
  540. {
  541.   int x, y;
  542.   UBYTE colour;
  543.   
  544.  
  545.   colour=1; /* Set colour to 1, white. */
  546.  
  547.   /* Set Draw Mode to normal: */
  548.   SetDrMd( my_window->RPort, JAM1 );
  549.   
  550.   for(x=0; x < MAX_WIDTH/40-2; x++)
  551.     for(y=0; y < MAX_HEIGHT/20-2; y++)
  552.     {
  553.       /* New colour to draw with */
  554.       SetAPen( my_window->RPort, colour );
  555.  
  556.       colour++;
  557.  
  558.       /* If colour is bigger than 3 (Orange) we change colour to 1 */
  559.       /* (white) again. (The boxes will therefore be drawn with the */
  560.       /* colours white, black, orange: */
  561.       if(colour > 3)
  562.         colour=1;
  563.     
  564.       Move( my_window->RPort, x*40+40, y*20+20 ); /* Top left corner. */
  565.       Draw( my_window->RPort, x*40+72, y*20+20 ); /* Out to the right. */
  566.       Draw( my_window->RPort, x*40+72, y*20+36 ); /* Down. */
  567.       Draw( my_window->RPort, x*40+40, y*20+36 ); /* Back to the left. */
  568.       Draw( my_window->RPort, x*40+40, y*20+20 ); /* Up again. */    
  569.     }
  570. }
  571.